package com.tool.app.util.date;

import cn.hutool.core.date.LocalDateTimeUtil;

import java.text.SimpleDateFormat;
import java.time.*;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

/**
 * 时间工具类
 *
 * @author vpp
 */
public class DateUtils {

    /**
     * 时区 - 默认
     */
    public static final String TIME_ZONE_DEFAULT = "GMT+8";

    /**
     * 秒转换成毫秒
     */
    public static final long SECOND_MILLIS = 1000;

    public static final String FORMAT_YEAR_MONTH_DAY = "yyyy-MM-dd";

    public static final String FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND = "yyyy-MM-dd HH:mm:ss";

    /**
     * 将 LocalDateTime 转换成 Date
     *
     * @param date LocalDateTime
     * @return LocalDateTime
     */
    public static Date of(LocalDateTime date) {
        if (date == null) {
            return null;
        }
        // 将此日期时间与时区相结合以创建 ZonedDateTime
        ZonedDateTime zonedDateTime = date.atZone(ZoneId.systemDefault());
        // 本地时间线 LocalDateTime 到即时时间线 Instant 时间戳
        Instant instant = zonedDateTime.toInstant();
        // UTC时间(世界协调时间,UTC + 00:00)转北京(北京,UTC + 8:00)时间
        return Date.from(instant);
    }

    /**
     * 将 Date 转换成 LocalDateTime
     *
     * @param date Date
     * @return LocalDateTime
     */
    public static LocalDateTime of(Date date) {
        if (date == null) {
            return null;
        }
        // 转为时间戳
        Instant instant = date.toInstant();
        // UTC时间(世界协调时间,UTC + 00:00)转北京(北京,UTC + 8:00)时间
        return LocalDateTime.ofInstant(instant, ZoneId.systemDefault());
    }

    public static Date addTime(Duration duration) {
        return new Date(System.currentTimeMillis() + duration.toMillis());
    }

    public static boolean isExpired(LocalDateTime time) {
        LocalDateTime now = LocalDateTime.now();
        return now.isAfter(time);
    }

    /**
     * 创建指定时间
     *
     * @param year  年
     * @param mouth 月
     * @param day   日
     * @return 指定时间
     */
    public static Date buildTime(int year, int mouth, int day) {
        return buildTime(year, mouth, day, 0, 0, 0);
    }

    /**
     * 创建指定时间
     *
     * @param year   年
     * @param mouth  月
     * @param day    日
     * @param hour   小时
     * @param minute 分钟
     * @param second 秒
     * @return 指定时间
     */
    public static Date buildTime(int year, int mouth, int day,
                                 int hour, int minute, int second) {
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.YEAR, year);
        calendar.set(Calendar.MONTH, mouth - 1);
        calendar.set(Calendar.DAY_OF_MONTH, day);
        calendar.set(Calendar.HOUR_OF_DAY, hour);
        calendar.set(Calendar.MINUTE, minute);
        calendar.set(Calendar.SECOND, second);
        calendar.set(Calendar.MILLISECOND, 0); // 一般情况下，都是 0 毫秒
        return calendar.getTime();
    }

    public static Date max(Date a, Date b) {
        if (a == null) {
            return b;
        }
        if (b == null) {
            return a;
        }
        return a.compareTo(b) > 0 ? a : b;
    }

    public static LocalDateTime max(LocalDateTime a, LocalDateTime b) {
        if (a == null) {
            return b;
        }
        if (b == null) {
            return a;
        }
        return a.isAfter(b) ? a : b;
    }

    /**
     * 是否今天
     *
     * @param date 日期
     * @return 是否
     */
    public static boolean isToday(LocalDateTime date) {
        return LocalDateTimeUtil.isSameDay(date, LocalDateTime.now());
    }

    /**
     * 是否昨天
     *
     * @param date 日期
     * @return 是否
     */
    public static boolean isYesterday(LocalDateTime date) {
        return LocalDateTimeUtil.isSameDay(date, LocalDateTime.now().minusDays(1));
    }

    /**
     * @description: 输入开始时间和结束时间获取指定分钟间隔的时间点列表
     * @author: 邱杭锐
     * @createDate: 2024/7/15 18:03
     * @param: [startTime, endTime]
     * @return: java.util.List<java.util.Date>
     */
    public static List<Date> getMinuteDateList(Date startTime, Date endTime, int amount) {
        List<Date> dates = new ArrayList<>();
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(startTime);
        while (calendar.getTime().before(endTime)) {
            dates.add(calendar.getTime());
            calendar.add(Calendar.MINUTE, amount);
        }
        // 确保结束时间也被包含在内
        if (calendar.getTime().equals(endTime)) {
            dates.add(calendar.getTime());
        }
        return dates;
    }

    /**
     * @description: 输入开始时间和结束时间，计算相差的小时数
     * @author: 邱杭锐
     * @createDate: 2024/7/24 16:05
     * @param: [startTime, endTime]
     * @return: double
     */
    public static double getTimeIntervalHours(Date startTime,Date endTime) {
        // 使用Calendar计算小时数差异
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(startTime);
        int startHours = calendar.get(Calendar.HOUR_OF_DAY);
        int startMinutes = calendar.get(Calendar.MINUTE);

        calendar.setTime(endTime);
        int endHours = calendar.get(Calendar.HOUR_OF_DAY);
        int endMinutes = calendar.get(Calendar.MINUTE);
        // 计算总小时数
        return endHours - startHours + (startMinutes-endMinutes)/60;
    }

    /**
     * @description: 输入开始时间和结束时间，计算相差的分钟数
     * @author: 邱杭锐
     * @createDate: 2024/8/21 21:00
     * @param: [startTime, endTime]
     * @return: int
     */
    public static int getTimeIntervalMinutes(Date startTime,Date endTime) {
        // 使用Calendar计算小时数差异
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(startTime);
        int startHours = calendar.get(Calendar.HOUR_OF_DAY);
        int startMinutes = calendar.get(Calendar.MINUTE);

        calendar.setTime(endTime);
        int endHours = calendar.get(Calendar.HOUR_OF_DAY);
        int endMinutes = calendar.get(Calendar.MINUTE);
        // 计算总小时数
        return (endHours - startHours) * 60 + (startMinutes-endMinutes);
    }

    public static Date localDateToDate(LocalDate localDate) {
        Instant instant = localDate.atStartOfDay(ZoneId.systemDefault()).toInstant();
        return Date.from(instant);
    }

    public static final String parseDateToStr(final String format, final Date date)
    {
        return new SimpleDateFormat(format).format(date);
    }


    public static LocalDate stringToLocalDate(String localDate) {
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern(FORMAT_YEAR_MONTH_DAY);
        return LocalDate.parse(localDate,formatter);
    }

    /**
     * 获取一天96点的数据
     * @return
     */
    public static List<String> get96PointList() {
        List<String> times = new ArrayList<>();
        for (int hour = 0; hour < 24; hour++) {
            for (int minute = 0; minute < 60; minute += 15) {
                String time = String.format("%02d%02d", hour, minute);
                times.add(time);
            }
        }
        return times;
    }

    /**
     * 获取一天t96点数据
     * @return
     */
    public static List<String> getT96PointList() {
        List<String> times = new ArrayList<>();
        for (int hour = 0; hour < 24; hour++) {
            for (int minute = 0; minute < 60; minute += 15) {
                String time = "t"+String.format("%02d%02d", hour, minute);
                times.add(time);
            }
        }
        return times;
    }
}
